package com.asen.commons.core.base.service.impl;

import com.asen.commons.core.base.domain.Core;
import com.asen.commons.core.base.dto.CommonInnerDto;
import com.asen.commons.core.base.dto.QueryDto;
import com.asen.commons.core.base.vo.DcPage;
import com.asen.commons.core.meta.dao.Condition;
import com.asen.commons.utils.*;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.asen.commons.exception.ServiceException;
import com.asen.commons.core.base.result.ApiResult;

import java.util.Collection;
import java.util.List;

/**
 * 远程服务
 *
 * @author Gary
 * @version 1.0
 * @date 2019-01-02
 */
public class RemoteService {

    /**
     * 查询详情，不包括显示属性
     *
     * @param serviceName
     * @param modelClazz
     * @param id
     * @param <T>
     * @return
     * @throws Exception
     */
    public <T extends Core> T get(String serviceName, Class<T> modelClazz, Long id) throws Exception {
        String path = "/inner/common/get?modelClass=" + modelClazz.getName() + "&id=" + id;
        return RestUtils.get(serviceName, path, modelClazz);
    }

    //public <T extends Core> T get(Class<T> modelClazz, Long id) throws Exception {
    //    String path = "/inner/common/get?modelClass=" + modelClazz.getName() + "&id=" + id;
    //    return RestUtils.get(modelClazz, path);
    //}

    /**
     * 根据condition查询
     *
     * @param serviceName
     * @param modelClazz
     * @param condition
     * @param <T>
     * @return
     * @throws Exception
     */
    public <T extends Core> T getBy(String serviceName, Class<T> modelClazz, Condition condition) throws Exception {
        String path = "/inner/common/getBy?modelClass=" + modelClazz.getName();
        return RestUtils.post(serviceName, path, condition, modelClazz);
    }

    //public <T extends Core> T getBy(Class<T> modelClazz, Condition condition) throws Exception {
    //    String path = "/inner/common/getBy?modelClass=" + modelClazz.getName();
    //    return RestUtils.post(modelClazz, path, condition, modelClazz);
    //}

    /**
     * 查询详情，不包括显示属性
     *
     * @param serviceName
     * @param modelClass
     * @param id
     * @return
     * @throws Exception
     */
    public JSONObject getJson(String serviceName, String modelClass, Long id) throws Exception {
        String path = "/inner/common/get?modelClass=" + modelClass + "&id=" + id;
        return RestUtils.get(serviceName, path, JSONObject.class);
    }

    /**
     * 获取vo，查询结果包括vo显示属性
     *
     * @param serviceName
     * @param modelClass
     * @param id
     * @return
     * @throws Exception
     */
    public Object getVo(String serviceName, String modelClass, Long id) throws Exception {
        String path = "/common/get?modelClass=" + modelClass + "&id=" + id;
        ApiResult apiResult = RestUtils.get(serviceName, path, ApiResult.class);
        if (!apiResult.isSuccess()) {
            throw new ServiceException(apiResult.getMessage());
        }
        return apiResult.getResult();
    }

    /**
     * 获取vo列表，查询结果包括vo显示属性
     */
    public DcPage<JSONObject> getVoList(String serviceName, String modelClass, QueryDto<JSONObject> queryDto) throws Exception {
        String path = "/common/getList?modelClass=" + modelClass;
        String result = RestUtils.post(serviceName, path, queryDto, String.class);
        ApiResult<DcPage<JSONObject>> apiResult = JSONObject.parseObject(result, new TypeReference<ApiResult<DcPage<JSONObject>>>() {
        });
        if (!apiResult.isSuccess()) {
            throw new ServiceException(apiResult.getMessage());
        }
        return apiResult.getResult();
    }

    public <T extends Core> List<T> getList(String serviceName, Class<T> modelClazz, Condition condition) throws Exception {
        String path = "/inner/common/list?modelClass=" + modelClazz.getName();
        String json = RestUtils.post(serviceName, path, condition, String.class);
        return JSONArray.parseArray(json, modelClazz);
    }

    /**
     * 获取list,组织隔离
     */
    public <T extends Core> List<T> getListIsolation(String serviceName, Class<T> modelClazz, Condition condition) throws Exception {
        String path = "/inner/common/listIsolation?modelClass=" + modelClazz.getName();
        String json = RestUtils.post(serviceName, path, condition, String.class);
        return JSONArray.parseArray(json, modelClazz);
    }

    public JSONArray getJSONArray(String serviceName, String modelClass, Condition condition) throws Exception {
        String path = "/inner/common/list?modelClass=" + modelClass;
        String json = RestUtils.post(serviceName, path, condition, String.class);
        return JSONArray.parseArray(json);
    }

    public <T extends Core> Integer count(String serviceName, Class<T> modelClazz, Condition condition) throws Exception {
        String path = "/inner/common/count?modelClass=" + modelClazz.getName();
        return RestUtils.post(serviceName, path, condition, Integer.class);
    }

    public <T extends Core> Integer countIsolation(String serviceName, Class<T> modelClazz, Condition condition) throws Exception {
        String path = "/inner/common/countIsolation?modelClass=" + modelClazz.getName();
        return RestUtils.post(serviceName, path, condition, Integer.class);
    }

    public <T extends Core> Integer count(String serviceName, String modelClazz, Condition condition) throws Exception {
        String path = "/inner/common/count?modelClass=" + modelClazz;
        return RestUtils.post(serviceName, path, condition, Integer.class);
    }

    public <T extends Core> Long add(String serviceName, Class<T> modelClazz, T model) throws Exception {
        String path = "/inner/common/add?modelClass=" + modelClazz.getName();
        return RestUtils.post(serviceName, path, model, Long.class);
    }

    public <T extends Core> List<Long> batchAdd(String serviceName, Class<T> modelClazz, List<T> list) throws Exception {
        String path = "/inner/common/batchAdd?modelClass=" + modelClazz.getName();
        return RestUtils.post(serviceName, path, list, List.class);
    }

    public <T extends Core> void update(String serviceName, Class<T> modelClazz, T model) throws Exception {
        String path = "/inner/common/update?modelClass=" + modelClazz.getName();
        RestUtils.post(serviceName, path, model);
    }

    public <T extends Core> List<Long> batchUpdate(String serviceName, Class<T> modelClazz, List<T> list) throws Exception {
        String path = "/inner/common/batchUpdate?modelClass=" + modelClazz.getName();
        return RestUtils.post(serviceName, path, list, List.class);
    }

    public <T extends Core> void updatePartial(String serviceName, Class<T> modelClazz, T model, String... partialFields) throws Exception {
        BaseAssert.notNull(serviceName, "参数serviceName不能空");
        BaseAssert.notNull(modelClazz, "参数modelClazz不能空");
        BaseAssert.notNull(model, "参数model不能空");
        BaseAssert.notEmpty(model.getId(), "参数model.getId()不能空");
        BaseAssert.notEmpty(partialFields, "参数partialFields不能空");
        CommonInnerDto dto = new CommonInnerDto();
        dto.setModel(model);
        dto.setPartialFields(partialFields);
        String path = "/inner/common/updatePartial?modelClass=" + modelClazz.getName();
        RestUtils.post(serviceName, path, dto);
    }

    public <T extends Core> void batchUpdatePartial(String serviceName, Class<T> modelClazz, Collection<T> models, String... partialFields) throws Exception {
        BaseAssert.notNull(serviceName, "参数serviceName不能空");
        BaseAssert.notNull(modelClazz, "参数modelClazz不能空");
        BaseAssert.notNull(models, "参数models不能空");
        for (T model : models) {
            BaseAssert.notEmpty(model.getId(), "参数model.getId()不能空");
        }
        BaseAssert.notEmpty(partialFields, "参数partialFields不能空");
        CommonInnerDto dto = new CommonInnerDto();
        dto.setModels(models);
        dto.setPartialFields(partialFields);
        String path = "/inner/common/batchUpdatePartial?modelClass=" + modelClazz.getName();
        RestUtils.post(serviceName, path, dto);
    }

    public <T extends Core> void batchRemove(String serviceName, Class<T> modelClazz, List<T> list) throws Exception {
        String path = "/inner/common/batchRemove?modelClass=" + modelClazz.getName();
        RestUtils.post(serviceName, path, list);
    }

    public <T extends Core> void remove(String serviceName, Class<T> modelClazz, Long id) throws Exception {
        String path = "/inner/common/remove?modelClass=" + modelClazz.getName() + "&id=" + id;
        RestUtils.post(serviceName, path);
    }

    public <T extends Core> void removeBy(String serviceName, Class<T> modelClazz, Condition condition) throws Exception {
        removeBy(serviceName, modelClazz, condition, false);
    }

    public <T extends Core> void removeByCompletely(String serviceName, Class<T> modelClazz, Condition condition) throws Exception {
        String path = "/inner/common/removeByCompletely?modelClass=" + modelClazz.getName() ;
        RestUtils.post(serviceName, path, condition);
    }

    public <T extends Core> void removeBy(String serviceName, Class<T> modelClazz, Condition condition, boolean updateTime) throws Exception {
        String path = "/inner/common/removeBy?modelClass=" + modelClazz.getName() + "&updateTime=" + updateTime;
        RestUtils.post(serviceName, path, condition);
    }

    public <T extends Core> void audit(String serviceName, Class<T> modelClazz, Long id) throws Exception {
        String path = "/inner/common/audit?modelClass=" + modelClazz.getName() + "&id=" + id;
        RestUtils.post(serviceName, path);
    }

    public <T extends Core> void unAudit(String serviceName, Class<T> modelClazz, Long id) throws Exception {
        String path = "/inner/common/unAudit?modelClass=" + modelClazz.getName() + "&id=" + id;
        RestUtils.post(serviceName, path);
    }

    /**
     * 从接口获取参数列表
     *
     * @param url 例如:http://scp-bas-service/inner/entrustCredit/getCreditLine
     * @return
     * @throws Exception
     */
    /*public List<UrlParams> getUrlParamsList(String url) throws Exception {
        if (StringUtils.isBlank(url)) {
            return null;
        }
        // 1.直接去除第一部分的http://
        url = url.replace("http://", "");
        if (!url.contains("/")) {
            return null;
        }
        // 将地址转为 服务和接口
        String serviceName = url.substring(0, url.indexOf("/"));
        String urlController = url.substring(url.indexOf("/"));
        if (StringUtils.isBlank(serviceName) || StringUtils.isBlank(urlController)) {
            return null;
        }
        ServiceNameEnum serviceNameEnum = ServiceNameEnum.getEnumByValue(serviceName);
        if (serviceNameEnum == null) {
            return null;
        }
        String path = "/inner/common/getUrlParamsList?url=" + urlController;
        String json = RestUtils.get(serviceNameEnum, path, String.class);
        return JSONArray.parseArray(json, UrlParams.class);
    }*/

    /**
     * 获取接口信息
     *
     * @param url 例如:http://scp-bas-service/inner/entrustCredit/getCreditLine
     */
    /*public UrlModel getUrlModel(String url) throws Exception {
        if (StringUtils.isBlank(url)) {
            return null;
        }
        // 1.直接去除第一部分的http://
        url = url.replace("http://", "");
        if (!url.contains("/")) {
            return null;
        }
        // 将地址转为 服务和接口
        String serviceName = url.substring(0, url.indexOf("/"));
        String urlController = url.substring(url.indexOf("/"));
        if (StringUtils.isBlank(serviceName) || StringUtils.isBlank(urlController)) {
            return null;
        }
        ServiceNameEnum serviceNameEnum = ServiceNameEnum.getEnumByValue(serviceName);
        if (serviceNameEnum == null) {
            return null;
        }
        String path = "/inner/common/getUrlModel?url=" + urlController;
        String json = RestUtils.get(serviceNameEnum, path, String.class);
        return JSONArray.parseObject(json, UrlModel.class);
    }*/
}
